<template>
  <!-- 内容区域：保留原结构不变 -->
  <div class="collapse-content" ref="contentRef" :style="computedContentStyle">
    <div
      v-show="isCollapsed && hideContent"
      style="position: absolute; background-color: white; height: 100%; width: 100%; z-index: 1"
    ></div>
    <!-- 步骤1：用容器包裹slot，加ref -->
    <div ref="slotContainerRef" class="slot-container">
      <slot />
      <!-- 插槽内容会渲染到这个容器里 -->
    </div>

    <!-- 控制栏：保留原slot结构 -->
    <slot name="handle-content">
      <component :is="computedIconComponent" :style="computedIconStyle" @click="changeCollapsed" />
    </slot>
  </div>
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'

// 1. 定义 props
const props = defineProps({
  direction: {
    type: String,
    default: 'bottom',
    validator: val => ['top', 'bottom', 'left', 'right'].includes(val)
  },
  iconSize: { type: Number, default: 25 },
  hideContent: { type: Boolean, default: true },
  defaultHeight: { type: String, default: '70px' },
  iconComponent: { type: [Object, String], default: null },
  contentStyle: { type: Object, default: () => ({}) },
  iconStyle: { type: Object, default: () => ({}) },
  initiallyCollapsed: { type: Boolean, default: false }
})

// 响应式变量
const slotHeight = ref(0)
const slotContainerRef = ref(null)
const isCollapsed = ref(props.initiallyCollapsed)
const contentRef = ref(null)
const transitionEnded = ref(true)
const iconMap = { top: 'ArrowUp', bottom: 'ArrowDown', left: 'ArrowRight', right: 'ArrowLeft' }

// 计算属性：图标组件
const computedIconComponent = computed(() => {
  if (props.iconComponent) return props.iconComponent
  return iconMap[props.direction]
})

// 计算属性：内容区域样式
const computedContentStyle = computed(() => {
  const sizeKey = ['top', 'bottom'].includes(props.direction) ? 'height' : 'width'
  let targetSize
  if (!isCollapsed.value) {
    // 折叠时，若有插槽高度则用插槽高度，否则用默认高度
    targetSize = slotHeight.value ? `${slotHeight.value}px` : props.defaultHeight
  } else {
    // 展开时用默认高度
    targetSize = props.defaultHeight
  }
  return {
    transition: 'all 0.3s ease',
    [sizeKey]: targetSize,
    ...props.contentStyle
  }
})

// 计算属性：图标样式
const computedIconStyle = computed(() => ({
  position: 'absolute',
  color: '#909399',
  left: '50%',
  bottom: '-5px',
  width: `${props.iconSize || 20}px`,
  height: `${props.iconSize || 20}px`,
  transition: 'transform 0.3s ease',
  transform: isCollapsed.value ? 'rotate(0)' : 'rotate(180deg)',
  transformOrigin: 'center center',
  zIndex: 2,
  ...props.iconStyle
}))

// 切换折叠/展开方法
const changeCollapsed = () => {
  if (!transitionEnded.value) return

  transitionEnded.value = false
  isCollapsed.value = !isCollapsed.value

  nextTick(() => {
    const el = contentRef.value
    if (el) {
      const onEnd = () => {
        transitionEnded.value = true
        el.removeEventListener('transitionend', onEnd)
      }
      el.addEventListener('transitionend', onEnd)
    }
  })

  emit('toggle', isCollapsed.value)
}

// 暴露方法
defineExpose({
  toggleCollapse: changeCollapsed,
  expand: () => {
    if (isCollapsed.value) changeCollapsed()
  },
  collapse: () => {
    if (!isCollapsed.value) changeCollapsed()
  },
  isCollapsed
})

// 事件触发
const emit = defineEmits(['toggle', 'expanded', 'collapsed'])
watch(isCollapsed, newVal => {
  if (newVal) {
    emit('collapsed')
  } else {
    emit('expanded')
  }
})

// 初始化及监听相关
let resizeObserver = null
onMounted(() => {
  getSlotHeight() // 首次获取高度

  // 用 ResizeObserver 监听插槽容器尺寸变化
  if (slotContainerRef.value) {
    resizeObserver = new ResizeObserver(entries => {
      nextTick(() => getSlotHeight())
    })
    resizeObserver.observe(slotContainerRef.value)
  }
})

onUnmounted(() => {
  // 停止 ResizeObserver 监听
  if (resizeObserver) {
    resizeObserver.disconnect()
  }
})

// 获取插槽高度方法
const getSlotHeight = () => {
  if (slotContainerRef.value) {
    slotHeight.value = slotContainerRef.value.offsetHeight
  }
}
</script>
<style scoped>
.collapse-content {
  position: relative;
  overflow: hidden;
  height: auto;
  width: 100%;
  transition: all 0.3s ease;
}
.slot-container {
  width: 100%;
  height: auto;
}
</style>